package com.glacier.framework.boot.autoconfigure.jackson;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.glacier.framework.boot.date.DatePattern;
import com.glacier.framework.boot.jackson.module.CustomJavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.TimeZone;

/**
 * date 2023-12-29 17:05
 * jackson 配置
 * 注意需要在 JacksonAutoConfiguration.class 之前进行装配，如果在它之后装配，注入的Jackson2ObjectMapperBuilderCustomizer不生效
 *
 * @author glacier
 * @version 1.0
 */
@Slf4j
@AutoConfiguration(before = JacksonAutoConfiguration.class)
@ConditionalOnClass(ObjectMapper.class)
public class JsonAutoConfiguration {

    /**
     * springboot 在构建ObjectMapper时默认使用这个构建器
     *
     * @return Jackson2ObjectMapperBuilderCustomizer
     */
    @Bean
    @ConditionalOnMissingBean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilder() {
        log.info("Jackson2ObjectMapperBuilderCustomizer 实例化");
        return builder -> {
            // 这部分也可以在 yaml 中配置
            builder
                    // 序列化时，对象为 null，是否抛异常
                    .failOnEmptyBeans(false)
                    // 反序列化时，json 中包含 pojo 不存在属性时，是否抛异常
                    .failOnUnknownProperties(false)
                    // 禁止将 java.util.Date, Calendar 序列化为数字(时间戳)
                    .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                    // 设置 java.util.Date, Calendar 序列化、反序列化的格式
                    .dateFormat(new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN))
                    // 设置 java.util.Date、Calendar 序列化、反序列化的时区
                    .timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()))
                    // NULL不参与序列化
                    .serializationInclusion(JsonInclude.Include.NON_EMPTY);
            // 配置 Jackson 序列化 BigDecimal 时使用的格式
            builder.serializerByType(BigDecimal.class, ToStringSerializer.instance);
            // 配置 Jackson 序列化 BigInteger 时使用的格式
            builder.serializerByType(BigInteger.class, ToStringSerializer.instance);
            // 配置 Jackson 序列化 Long 时使用的格式
            builder.serializerByType(Long.class, ToStringSerializer.instance);
            // 配置时间格式
            builder.modules(new CustomJavaTimeModule());
        };
    }
}
